package com.soriya.nestlive.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.soriya.nestlive.constant.CommonConst;
import com.soriya.nestlive.entity.ChannelEntity;
import com.soriya.nestlive.entity.LiveEntity;
import com.soriya.nestlive.entity.PageResult;
import com.soriya.nestlive.entity.UserEntity;
import com.soriya.nestlive.entity.param.LiveListParam;
import com.soriya.nestlive.entity.vo.LiveDetailVo;
import com.soriya.nestlive.mapper.LiveMapper;
import com.soriya.nestlive.service.ChannelService;
import com.soriya.nestlive.service.LiveService;
import com.soriya.nestlive.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class LiveServiceImpl extends ServiceImpl<LiveMapper, LiveEntity> implements LiveService {

    @Autowired
    private ChannelService channelService;

    @Override
    public PageResult<LiveEntity> pageQuery(Page<LiveEntity> page, LiveListParam param) {
        LambdaQueryWrapper<LiveEntity> wrapper = new LambdaQueryWrapper<>();
        page(page, wrapper);
        return PageResult.from(page);
    }

    @Override
    public LiveDetailVo getByChannelId(Long channelId) {

        MPJLambdaWrapper<LiveEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(LiveEntity.class)
                .select(UserEntity::getNickname)
                .select(UserEntity::getAvatar)
                .leftJoin(ChannelEntity.class, ChannelEntity::getId, LiveEntity::getChannelId)
                .leftJoin(UserEntity.class, UserEntity::getId, ChannelEntity::getUserId)
                .eq(ChannelEntity::getId, channelId)
                .orderByDesc(LiveEntity::getCreateTime)
                .last("LIMIT 1");

        return baseMapper.selectJoinOne(LiveDetailVo.class, wrapper);
    }

    @Override
    public PageResult<LiveDetailVo> getByCategoryId(Long categoryId, Integer current, Integer size) {
        int position = (current - 1) * size;

        int count = baseMapper.selectByCategoryIdCount(categoryId);

        List<LiveDetailVo> list = baseMapper.selectByCategoryId(categoryId, position, size);

        return new PageResult<>(
                count,
                size,
                count / size,
                position,
                list
        );
    }

    @Override
    public PageResult<LiveDetailVo> pageList(Page<LiveDetailVo> page) {
        MPJLambdaWrapper<LiveEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(LiveEntity.class)
                .select(UserEntity::getNickname)
                .select(UserEntity::getAvatar)
                .leftJoin(ChannelEntity.class, ChannelEntity::getId, LiveEntity::getChannelId)
                .leftJoin(UserEntity.class, UserEntity::getId, ChannelEntity::getUserId)
                .eq(ChannelEntity::getLiveState, 1)
                .orderByDesc(LiveEntity::getViewers)
                .last(", RAND()");
        baseMapper.selectJoinPage(page, LiveDetailVo.class, wrapper);
        return PageResult.from(page);
    }

    @Override
    public void updateDuration(Long channelId) {
//        MPJLambdaWrapper<LiveEntity> wrapper = new MPJLambdaWrapper<>();
//        wrapper.selectAll(LiveEntity.class)
//                .leftJoin(ChannelEntity.class, ChannelEntity::getId, LiveEntity::getChannelId)
//                .eq(ChannelEntity::getUserId, userId)
//                .orderByDesc(LiveEntity::getStartTime)
//                .last("LIMIT 1");

        LambdaQueryWrapper<LiveEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LiveEntity::getChannelId, channelId)
                .orderByDesc(LiveEntity::getStartTime)
                .last("LIMIT 1");


        LiveEntity liveEntity = baseMapper.selectOne(wrapper);

        Date startTime = liveEntity.getStartTime();
        Date date = new Date();
        long duration = date.getTime() - startTime.getTime();

        liveEntity.setDuration(BigDecimal.valueOf((double) duration / 1000F / 60F));
        updateById(liveEntity);
    }

    @Override
    public boolean stopStream(Long channelId) {
        ChannelEntity channelEntity = new ChannelEntity();
        channelEntity.setId(channelId);
        channelEntity.setLiveState(0);
        channelService.updateById(channelEntity);

        String key = CommonConst.STREAMING_PREFIX + channelId;
        RedisUtil.delete(key);
        return true;
    }

    @Override
    public List<LiveEntity> getHistory(Long channelId) {
        LambdaQueryWrapper<LiveEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LiveEntity::getChannelId, channelId)
                .orderByDesc(LiveEntity::getStartTime)
                .last("LIMIT 20");

        return list(wrapper);
    }

}
